#include "c1218_erridx.h"
#include "c1218_stack.h"
#include "c1218_pl.h"

static struct c1218_pl_ops def_pl_ops =
{
	.read = ansi_meter_read,
	.write = ansi_meter_write,
	.flush = ansi_meter_flush,
	.init = ansi_meter_init,
	.prefetch = ansi_meter_prefetch,
};

int c1218_pl_init(c1218_pl_t *pl)
{
	c1218_stack_t *stack = pl_to_stack(pl);

	pl->Aqport = stack->port;
	pl->baudrate = DEF_BAUDRATE;
	pl->ops = &def_pl_ops;

	return pl->ops->init(pl->Aqport);
}

int c1218_pl_release(c1218_pl_t *pl)
{
	return pl->ops->release(pl->Aqport);
}

int c1218_pl_iflush(c1218_pl_t *pl)
{
	return pl->ops->flush(pl->Aqport);
}

int c1218_pl_write(c1218_pl_t *pl, uint8_t *buf, int size)
{
	pl->ops->write(pl->Aqport, buf, size);
	return size;
}

int c1218_pl_prefetch(c1218_pl_t *pl, uint8_t *buf, int size)
{
	int32_t rsize = pl->ops->prefetch(pl->Aqport, buf, size);

	return rsize;
}

int c1218_pl_read(c1218_pl_t *pl, uint8_t *buf, int size)
{
	int32_t rsize = pl->ops->read(pl->Aqport, buf, size);

	if (rsize < 0) {
#ifdef __LINUX__
		LOGD("PL encounter read I/O error, libc erridx: %d\n", erridx);
#else
		LOGD("PL encounter read I/O error\n");
#endif
	} else {
		LOGD("PL << %d bytes.buf[0] is %d\n", rsize, buf[0]);
	}

	return rsize;
}

/* Just for testing */
/*
int c1218_pl_run(c1218_pl_t *pl)
{
	char *msg;
	char buf[BUFFCACHE_SIZE] = { 0 };
	int rsize, wsize;
	c1218_stack_t *stack = pl_to_stack(pl);

	if (!stack->is_client && !stack->is_device)
		return -1;

	if (stack->is_client)
		msg = "hello C12.18 Device!!!";
	else
		msg = "hello C12.18 Client!!!";

	while (1) {
		wsize = pl->ops->write((uint8_t *)msg, strlen(msg) + 1);
		if (wsize < strlen(msg) + 1) {
			LOGE("PL: fail to send testing msg.\n");
			return -1;
		}
		LOGI(">> %s\n", msg);
		rsize = pl->ops->read((uint8_t *)buf, (uint16_t)sizeof(buf));
		if (rsize < 0) {
			perror("read");
		}
		LOGI("<< %s\n", buf);
		LOGI("sleep 1s...\n");
		sleep(1);
	}

	return 0;
}*/

int c1218_pl_set_baudrate(c1218_pl_t *pl, uint8_t baudrate)
{
	if (pl->baudrate == baudrate)
		return 0;

	pl->baudrate = baudrate;
	return pl->ops->set_baudrate(baudrate);
}
